/**
 * 
 */
package com.zc.spring.serviceimpl;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.zc.spring.util.Formate;

/**
 * @author ZhangCheng
 * @time 2019年11月1日
 */
@Aspect // 该标签把LoggerAspect类声明为一个切面
//@Order(1)  //设置切面的优先级：如果有多个切面，可通过设置优先级控制切面的执行顺序（数值越小，优先级越高）
@Component
public class AopExampleHandlerAnnotate {
//	@Pointcut("execution(* com.zc.spring.serviceimpl.*.print*())")
	@Pointcut("execution(* com.zc.spring.serviceimpl.*.print*(..))")
	public void pointCut() {
	}

	@After("pointCut()")
	public void printNowWorkingTime() {
		System.out.println("后置通知 " + this.getClass().getSimpleName() + " Says Now：" + Formate.getNowTime());
	}

	@AfterThrowing(value = "pointCut()", throwing = "e")
	public void doException(JoinPoint j, Exception e) {
		System.out.println("异常！信息是：" + e.getMessage());
	}

	@Before("pointCut()")
	public void doBefore() {
		System.out.println("前置通知" + this.getClass().getSimpleName());
	}

	@AfterReturning(value = "pointCut()&&args(a)", returning = "ret")
	public void doReturning(Object ret, String a) {
		if (ret != null) {
//			System.out.println(aop+"*********");
			System.out.println("*******************");
			System.out.println("返回通知 doReturning...." + ret);
		} else {
			System.out.println("返回通知 doReturning....");
		}

	}

	@Around("pointCut()")
	// 对于单个的通知来说，around环绕通知，只要开始就会一直执行完后再继续执行其他的
	public Object doAround(ProceedingJoinPoint pJP) throws Throwable {
		Object ret = null;
		String methodName = pJP.getSignature().getName();
		try {
			// 前置通知
			System.out.println("This is the Method of " + methodName + " starting... here is params"
					+ Arrays.asList(pJP.getArgs()));
			ret = pJP.proceed();
			System.out.println("This is the returning of " + methodName + "end. ret = " + ret);
		} catch (Throwable e) {
			System.out.println("This is the" + methodName + " exception. Message is " + e.getMessage());
			throw new Throwable();
		}
		System.out.println("This is the " + methodName + "end");
		return ret;
	}

}
